package com.woniu.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.woniu.constants.RedisConstants;
import com.woniu.constants.WeChatConstants;
import com.woniu.entity.InviteFireworksRecord;
import com.woniu.entity.RedPacketPool;
import com.woniu.entity.SysConfig;
import com.woniu.entity.WechatTemplateMessage;
import com.woniu.mapper.InviteFireworksRecordMapper;
import com.woniu.mapper.RedPacketPoolMapper;
import com.woniu.mapper.SysConfigMapper;
import com.woniu.mapper.WechatTemplateMessageMapper;
import com.woniu.service.RedPacketPoolService;
import com.woniu.utils.RedPacketUtil;
import com.woniu.utils.RedisUtil;
import com.woniu.utils.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author LXB
 * @Date 2024/1/7 20:58
 * @Description
 **/
@Slf4j
@Component
@EnableScheduling
public class RedPacketTask {

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private InviteFireworksRecordMapper inviteFireworksRecordMapper;

    @Autowired
    private RedPacketPoolMapper redPacketPoolMapper;

    @Autowired
    private RedPacketPoolService redPacketPoolService;

    @Autowired
    private WechatTemplateMessageMapper wechatTemplateMessageMapper;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 监控新用户，达到规则发红包
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void MonitorNewUser(){
        SysConfig sysConfig = sysConfigMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
                .orderByDesc(SysConfig::getUpdateTime)
                .last(" limit 1"));
        if (sysConfig == null){
            return;
        }
        String nowStartDate = TimeUtil.getNowStartDate();
        String nowEndDate = TimeUtil.getNowEndDate();

        // 今日已派送的红包
        Long nowDateCount = redPacketPoolMapper.findCountByNowDate(nowStartDate, nowEndDate);

        // 随机出红包
        //List<RedPacketPool> redPacketPools = RedPacketUtil.assRedPacket(sysConfig.getRedEinmalTotalMoney(), sysConfig.getRedEinmalNumber(),sysConfig.getRedOneMax());
        // 固定红包
        List<RedPacketPool> redPacketPools = RedPacketUtil.assRedPacketFixed(sysConfig.getRedOneMinNum(), sysConfig.getRedOneMaxNum(), sysConfig.getRedOneMin(), sysConfig.getRedOneMax());
        int nowHour = LocalDateTime.now().getHour();
        if (nowHour == 0 && nowDateCount == 0L){
            List<RedPacketPool> zeroRedPackets;
            // 如果配置的0点固定红包数量大于0，则使用此配置
            if (sysConfig.getZeroPointRedNumber() != null && sysConfig.getZeroPointRedNumber() > 0){
                zeroRedPackets = RedPacketUtil.assRedPacketFixed(sysConfig.getZeroPointRedNumber(), 0, sysConfig.getRedOneMin(), sysConfig.getRedOneMax());
            }else {
                zeroRedPackets = new ArrayList<>(redPacketPools);
            }

            // 判断当天是否已经派发过大金额的红包
            if (sysConfig.getRedOneRandomMin() != null && sysConfig.getRedOneRandomMin() > 0d){

                if (!redPacketPoolMapper.exists(new LambdaQueryWrapper<RedPacketPool>()
                        .between(RedPacketPool::getCreateTime,nowStartDate,nowEndDate)
                        .ge(RedPacketPool::getRedPacketMoney,sysConfig.getRedOneRandomMin()))){

                    List<RedPacketPool> redPacketRandoms = RedPacketUtil.assRedPacketRandom(sysConfig.getRedOneRandomTotalMoney(), sysConfig.getRedOneRandomNum(),
                            String.valueOf(sysConfig.getRedOneRandomMin()), String.valueOf(sysConfig.getRedOneRandomMax()));
                    // 添加随机大金额红包
                    if (!CollectionUtils.isEmpty(redPacketRandoms)){
                        zeroRedPackets.addAll(redPacketRandoms);
                    }

                }


            }

            // 新增派送的红包
            redPacketPoolService.saveBatch(zeroRedPackets);

            return;
        }


        // 先查询目前新人总数
        List<InviteFireworksRecord> inviteFireworksRecords = inviteFireworksRecordMapper.findListByTimeAndFsoAndIsrp(nowStartDate, nowEndDate,sysConfig.getNewUserNumber());
        // 空的直接返回
        if (CollectionUtils.isEmpty(inviteFireworksRecords)){
            return;
        }
        // 判断人数是否达到派送红包的人数
        if (inviteFireworksRecords.size() < sysConfig.getNewUserNumber()){
            return;
        }

        // 判断派发过的红包总数量是否已经超过（配置的数量-派送红包的人数）
        if (nowDateCount > (sysConfig.getRedEverydayMaxNum() - sysConfig.getNewUserNumber())){
            return;
        }

        // 判断派发过的红包总金额是否已经超过(配置的总金额-配置的单次发红包金额)
        double sumMoneyByNowDate = redPacketPoolMapper.findSumMoneyByNowDate(nowStartDate, nowEndDate);
        if (sumMoneyByNowDate > (double) (sysConfig.getRedEverydayMaxMoney() - sysConfig.getRedEinmalTotalMoney())){
            return;
        }



        // 把新人的派送红包记录改为已派送(其实就是这个记录已经用过了)
        List<Integer> recordsIds = inviteFireworksRecords.stream().map(InviteFireworksRecord::getId).collect(Collectors.toList());

        Boolean flag = transactionTemplate.execute(e -> {

            if (inviteFireworksRecordMapper.update(null,new LambdaUpdateWrapper<InviteFireworksRecord>()
                    .in(InviteFireworksRecord::getId,recordsIds)
                    .set(InviteFireworksRecord::getSendRedPacket,true)) <= 0){
                return Boolean.FALSE;
            }

            // 新增派送的红包
            redPacketPoolService.saveBatch(redPacketPools);


            return Boolean.TRUE;
        });
        // 如果派发成功，判断时间在7-22点之间，则下发订阅消息和公众号消息
        if (Boolean.TRUE.equals(flag)){
            if (nowHour >= 7 && nowHour <= 22){
                wechatTemplateMessageMapper.update(null,new LambdaUpdateWrapper<WechatTemplateMessage>()
                        .eq(WechatTemplateMessage::getId, WeChatConstants.WECHAT_TEMPLATE_REDPACKET)
                        .set(WechatTemplateMessage::getSendStatus,true)
                        .set(WechatTemplateMessage::getUpdateTime,new Date()));
//                if (!redisUtil.exists(RedisConstants.REDPACKET_SEND_PROGRAM)){
//                    log.info("发红包了~");
//                    redisUtil.setString(RedisConstants.REDPACKET_SEND_PROGRAM,TimeUtil.calculateTime());
//                }
                // 红包开抢通知到公众号
//                if (!redisUtil.exists(RedisConstants.REDPACKET_SEND_PUBLIC)){
//                    redisUtil.setString(RedisConstants.REDPACKET_SEND_PUBLIC,TimeUtil.calculateTime());
//                }

            }
        }

    }

}
